﻿#include <Sys\RenderUnit\SysRenderDatagram\PRIMITIVERD.HPP>
#include <Render\Render_Win32\Render_Win32_D3D\RENDER_WIN32_D3D9.HPP>
#include <Sys\RenderUnit\SYSDDCLASSID.HPP>
#include <Sys\RenderUnit\SysDatagramDisposal_D3D\VERTEXREGISTRYDDD3D9.HPP>
#include <Sys\RenderUnit\SysDatagramDisposal_D3D\POSTDRAWDDD3D9.HPP>
#include <SLIST.HPP>

using namespace CxxlMan;
using namespace Cxxl3D;

// 頂點數量和索引數量，定義在 CVertexDDD3D.cpp
// extern C3D_USINT g_VertexNum, g_IndexNum;

// 清除 MutiTexture 恢復內定值，定義在 CMutiTextureDDD3D.cpp
//extern void cxxlFASTCALL CMutiTextureDD_2D_D3D9_Clear(LPDIRECT3DDEVICE9 pDEVICE9);


class CPostDrawDDD3D9:public IPostDrawDDD3D9
{
  Smart_Ptr<SList<IPostDrawNotice,true> > m_IPostDrawNotice_Ptr;

  virtual void cxxlFASTCALL Add(const CxxlMan::Smart_Ptr<IPostDrawNotice> &IPostDrawNotice_Arg)
  {
    m_IPostDrawNotice_Ptr->Push_Back(IPostDrawNotice_Arg);
  }
  virtual void cxxlFASTCALL Del(const CxxlMan::Smart_Ptr<IPostDrawNotice> &IPostDrawNotice_Arg)
  {
    m_IPostDrawNotice_Ptr->Delete(IPostDrawNotice_Arg);
  }
  virtual bool cxxlFASTCALL Exec(const Smart_Ptr<IRenderDatagramDisposalCenterD3d> &IRenderDatagramDisposalCenter_Arg,
    const Smart_Ptr<IRenderDatagram> &IRenderDatagram_Arg, LPDIRECT3DDEVICE9 pDEVICE9)
  {
    return true;
  }


public:
  // Constructor
  CPostDrawDDD3D9()
    :cxxlObject(CxxlMan::Spirit_Easy),
     m_IPostDrawNotice_Ptr(new SList<IPostDrawNotice,true>,this)
  {
  }

  // Destructor
  ~CPostDrawDDD3D9()
  {
  }


  void cxxlFASTCALL Notice(LPDIRECT3DDEVICE9 pDEVICE9)
  {
    Smart_Ptr<cxxlList<IPostDrawNotice> > IPostDrawNotice_List =
      m_IPostDrawNotice_Ptr->cxxlList_Create();

    unsigned long Count = IPostDrawNotice_List->GetCount();
    IPostDrawNotice_List->ResetPT(toHead);
    for(Smart_Ptr<IPostDrawNotice> IPostDrawNotice_Ptr = (*IPostDrawNotice_List)++; 
      Count > 0; 
      --Count,IPostDrawNotice_Ptr = (*IPostDrawNotice_List)++)
    {
      IPostDrawNotice_Ptr->Notice(pDEVICE9);
    }    
  }
};

cxxlObject *cxxlFASTCALL New_CPostDrawDDD3D9()
{
  return new CPostDrawDDD3D9();
}

/*********************************************************/

class CTrianglesStripDD_D3D9:public IDatagramDisposal_D3d9
{
  Smart_Ptr<IVertexRegistryDDD3D9> m_IVertexRegistryDDD3D9_Ptr;
  Smart_Ptr<CPostDrawDDD3D9> m_CPostDrawDDD3D9_Ptr;


  virtual bool cxxlFASTCALL Exec(const Smart_Ptr<IRenderDatagramDisposalCenterD3d> &IRenderDatagramDisposalCenterD3d_Arg,
    const Smart_Ptr<IRenderDatagram> &IRenderDatagram_Arg, LPDIRECT3DDEVICE9 pDEVICE9)
  {
    // 第一次被叫用才會取得
    if(m_IVertexRegistryDDD3D9_Ptr.isNULL())
      m_IVertexRegistryDDD3D9_Ptr = Smart_Cast<IVertexRegistryDDD3D9>(IRenderDatagramDisposalCenterD3d_Arg->GetIDatagramDisposal_D3d9(IVertexRegistryD3D9_ClassID));

    Smart_Ptr<IVertexDD> IVertexDD_Ptr = m_IVertexRegistryDDD3D9_Ptr->Get();

    C3D_USINT VertexNum, IndexNum;
    IVertexDD_Ptr->Get_VertexNum_IndexNum(VertexNum, IndexNum);

    // 第一次被叫用才會取得
    if(m_CPostDrawDDD3D9_Ptr.isNULL())
      m_CPostDrawDDD3D9_Ptr = Smart_Cast<CPostDrawDDD3D9>(IRenderDatagramDisposalCenterD3d_Arg->GetIDatagramDisposal_D3d9(IPostDrawDDD3D9_ClassID));

    Smart_Ptr<ITrianglesStripRD> ITrianglesStripRD_Ptr = (ITrianglesStripRD*)GetDefaultInterface(IRenderDatagram_Arg);

    // 開始下繪圖指令
    pDEVICE9->BeginScene(); 

    if(VertexNum && IndexNum)
    {
      pDEVICE9->DrawIndexedPrimitive(
		    D3DPT_TRIANGLESTRIP, // 指定所要畫的基本圖形種類
		    0, 
		    0, // 會使用的最小頂點編號, 事實上沒太大用處
        VertexNum, // 頂點陣列裡有幾個頂點
		    0, 
		    IndexNum - 2 // 要畫出幾個基本圖形
      );

    }


  	// 宣告所有的繪圖指令都下完了
	  pDEVICE9->EndScene(); 

    m_CPostDrawDDD3D9_Ptr->Notice(pDEVICE9);

    return true;
  }


public:
  // Constructor
  CTrianglesStripDD_D3D9()
   :cxxlObject(Spirit_Easy),
   m_IVertexRegistryDDD3D9_Ptr(NULL,this),
   m_CPostDrawDDD3D9_Ptr(NULL,this)
  {
  }

  // Destructor
  virtual ~CTrianglesStripDD_D3D9()
  {
  }
};

cxxlObject *cxxlFASTCALL New_CTrianglesStripDD_D3D9()
{
  return new CTrianglesStripDD_D3D9;
}

/*********************************************************/

class CTrianglesListDD_D3D9:public IDatagramDisposal_D3d9
{
  Smart_Ptr<IVertexRegistryDDD3D9> m_IVertexRegistryDDD3D9_Ptr;
  Smart_Ptr<CPostDrawDDD3D9> m_CPostDrawDDD3D9_Ptr;

  virtual bool cxxlFASTCALL Exec(const Smart_Ptr<IRenderDatagramDisposalCenterD3d> &IRenderDatagramDisposalCenterD3d_Arg,
    const Smart_Ptr<IRenderDatagram> &IRenderDatagram_Arg, LPDIRECT3DDEVICE9 pDEVICE9)
  {

    // 第一次被叫用才會取得
    if(m_IVertexRegistryDDD3D9_Ptr.isNULL())
      m_IVertexRegistryDDD3D9_Ptr = Smart_Cast<IVertexRegistryDDD3D9>(IRenderDatagramDisposalCenterD3d_Arg->GetIDatagramDisposal_D3d9(IVertexRegistryD3D9_ClassID));

    Smart_Ptr<IVertexDD> IVertexDD_Ptr = m_IVertexRegistryDDD3D9_Ptr->Get();

    C3D_USINT VertexNum, IndexNum;
    IVertexDD_Ptr->Get_VertexNum_IndexNum(VertexNum, IndexNum);

    // 第一次被叫用才會取得
    if(m_CPostDrawDDD3D9_Ptr.isNULL())
      m_CPostDrawDDD3D9_Ptr = Smart_Cast<CPostDrawDDD3D9>(IRenderDatagramDisposalCenterD3d_Arg->GetIDatagramDisposal_D3d9(IPostDrawDDD3D9_ClassID));

    
    Smart_Ptr<ITrianglesListRD> ITrianglesListRD_Ptr = (ITrianglesListRD*)GetDefaultInterface(IRenderDatagram_Arg);

    // 開始下繪圖指令
    pDEVICE9->BeginScene(); 

    if(VertexNum && IndexNum)
    {
      pDEVICE9->DrawIndexedPrimitive(
		    D3DPT_TRIANGLELIST, // 指定所要畫的基本圖形種類
		    0, 
		    0, // 會使用的最小頂點編號, 事實上沒太大用處
        VertexNum, // 頂點陣列裡有幾個頂點`
		    0, 
		    IndexNum / 3 // 要畫出幾個基本圖形
      );
    }

  	// 宣告所有的繪圖指令都下完了
	  pDEVICE9->EndScene();

    m_CPostDrawDDD3D9_Ptr->Notice(pDEVICE9);

    return true;
  }


public:
  // Constructor
  CTrianglesListDD_D3D9()
   :cxxlObject(Spirit_Easy),
   m_IVertexRegistryDDD3D9_Ptr(NULL,this),
   m_CPostDrawDDD3D9_Ptr(NULL,this)
  {
  }

  // Destructor
  virtual ~CTrianglesListDD_D3D9()
  {
  }
};

cxxlObject *cxxlFASTCALL New_CTrianglesListDD_D3D9()
{
  return new CTrianglesListDD_D3D9;
}

/****************************************************************/

